package com.duojuhe.coremodule.tracking.service.impl;

import com.duojuhe.common.annotation.DataScopeFilter;
import com.duojuhe.common.bean.UserTokenInfoVo;
import com.duojuhe.common.enums.SystemEnum;
import com.duojuhe.common.exception.base.DuoJuHeException;
import com.duojuhe.common.result.ErrorCodes;
import com.duojuhe.common.result.PageResult;
import com.duojuhe.common.result.ServiceResult;
import com.duojuhe.common.utils.idgenerator.UUIDUtils;
import com.duojuhe.common.utils.page.PageHelperUtil;
import com.duojuhe.coremodule.BaseService;
import com.duojuhe.coremodule.tracking.entity.TrackingCategory;
import com.duojuhe.coremodule.tracking.entity.TrackingProcessItem;
import com.duojuhe.coremodule.tracking.mapper.TrackingCategoryMapper;
import com.duojuhe.coremodule.tracking.mapper.TrackingProcessItemMapper;
import com.duojuhe.coremodule.tracking.pojo.dto.processitem.*;
import com.duojuhe.coremodule.tracking.service.TrackingProcessItemService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
public class TrackingProcessItemServiceImpl extends BaseService implements TrackingProcessItemService {
    @Resource
    private TrackingCategoryMapper trackingCategoryMapper;
    @Resource
    private TrackingProcessItemMapper trackingProcessItemMapper;

    /**
     * 【查询所有溯源流程项目】溯源流程项目管理
     * @param req
     * @return
     */
    @DataScopeFilter
    @Override
    public ServiceResult<PageResult<List<QueryTrackingProcessItemPageRes>>> queryTrackingProcessItemPageResList(QueryTrackingProcessItemPageReq req) {
        PageHelperUtil.orderByAndStartPage(req, "sort desc,operationTime desc,updateTime desc,itemId desc");
        List<QueryTrackingProcessItemPageRes> list = trackingProcessItemMapper.queryTrackingProcessItemPageResList(req);
        return PageHelperUtil.returnServiceResult(req, list);
    }

    /**
     * 【批量保存】批量保存溯源流程项目溯源流程项目
     * @param req
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public ServiceResult batchSaveTrackingProcessItem(BatchSaveTrackingProcessItemReq req) {
        //当前登录用户
        UserTokenInfoVo userTokenInfoVo = getCurrentLoginUserInfoDTO();
        //租户id
        String tenantId = userTokenInfoVo.getTenantId();
        //检查流程类别
        checkTrackingCategoryId(req.getTrackingCategoryId(),tenantId);
        //当前时间
        Date nowDate = new Date();
        //需要批量插入的数据对象
        List<TrackingProcessItem> processItemList = new ArrayList<TrackingProcessItem>();
        for (String transportCode:req.getTransportCodeList()){
            TrackingProcessItem processItem = new TrackingProcessItem();
            processItem.setItemId(UUIDUtils.getUUID32());
            processItem.setTransportCode(transportCode);
            processItem.setTrackingCategoryId(req.getTrackingCategoryId());
            processItem.setStatusCode(SystemEnum.STATUS.NORMAL.getKey());
            processItem.setSort(0);
            processItem.setDescription(req.getDescription());
            processItem.setOperatorName(req.getOperatorName());
            processItem.setOperationTime(req.getOperationTime());
            processItem.setCreateTime(nowDate);
            processItem.setUpdateTime(nowDate);
            processItem.setCreateUserId(userTokenInfoVo.getUserId());
            processItem.setUpdateUserId(userTokenInfoVo.getUserId());
            processItem.setCreateDeptId(userTokenInfoVo.getCreateDeptId());
            processItem.setTenantId(tenantId);
            //数据项集合
            processItemList.add(processItem);
        }
        //批量插入
        if (!processItemList.isEmpty()){
            trackingProcessItemMapper.batchInsertListUseAllCols(processItemList);
        }
        List<String> itemIdList = processItemList.stream().map(TrackingProcessItem::getItemId).collect(Collectors.toList());
        return ServiceResult.ok(itemIdList);
    }

    /**
     * 【保存】溯源流程项目溯源流程项目
     * @param req
     * @return
     */
    @Override
    public ServiceResult saveTrackingProcessItem(SaveTrackingProcessItemReq req) {
        //当前登录用户
        UserTokenInfoVo userTokenInfoVo = getCurrentLoginUserInfoDTO();
        //租户id
        String tenantId = userTokenInfoVo.getTenantId();
        //检查流程类别
        checkTrackingCategoryId(req.getTrackingCategoryId(),tenantId);
        //流程项目id
        String itemId = UUIDUtils.getUUID32();
        //当前时间
        Date nowDate = new Date();
        TrackingProcessItem processItem = new TrackingProcessItem();
        processItem.setItemId(itemId);
        processItem.setTransportCode(req.getTransportCode());
        processItem.setTrackingCategoryId(req.getTrackingCategoryId());
        processItem.setStatusCode(SystemEnum.STATUS.NORMAL.getKey());
        processItem.setSort(0);
        processItem.setDescription(req.getDescription());
        processItem.setOperatorName(req.getOperatorName());
        processItem.setOperationTime(req.getOperationTime());
        processItem.setCreateTime(nowDate);
        processItem.setUpdateTime(nowDate);
        processItem.setCreateUserId(userTokenInfoVo.getUserId());
        processItem.setUpdateUserId(userTokenInfoVo.getUserId());
        processItem.setCreateDeptId(userTokenInfoVo.getCreateDeptId());
        processItem.setTenantId(userTokenInfoVo.getTenantId());
        trackingProcessItemMapper.insertSelective(processItem);
        return ServiceResult.ok(itemId);
    }


    /**
     * 【修改】溯源流程项目溯源流程项目
     * @param req
     * @return
     */
    @Override
    public ServiceResult updateTrackingProcessItem(UpdateTrackingProcessItemReq req) {
        //流程项目id
        String itemId = req.getItemId();
        TrackingProcessItem trackingProcessItemOld = trackingProcessItemMapper.selectByPrimaryKey(itemId);
        if (trackingProcessItemOld==null){
            return ServiceResult.fail(ErrorCodes.PARAM_ERROR);
        }
        //检查流程类别
        checkTrackingCategoryId(req.getTrackingCategoryId(),trackingProcessItemOld.getTenantId());
        //当前时间
        Date nowDate = new Date();
        TrackingProcessItem processItem = new TrackingProcessItem();
        processItem.setItemId(itemId);
        processItem.setTrackingCategoryId(req.getTrackingCategoryId());
        processItem.setDescription(req.getDescription());
        processItem.setOperatorName(req.getOperatorName());
        processItem.setOperationTime(req.getOperationTime());
        processItem.setUpdateTime(nowDate);
        processItem.setUpdateUserId(getCurrentLoginUserId());
        trackingProcessItemMapper.updateByPrimaryKeySelective(processItem);
        return ServiceResult.ok(itemId);
    }

    /**
     * 【删除】根据溯源流程项目ID删除溯源流程项目，注意一次仅能删除一个溯源流程项目，存在绑定关系的则不能删除
     * @param req
     * @return
     */
    @Override
    public ServiceResult deleteTrackingProcessItemByItemId(TrackingProcessItemIdReq req) {
        //流程项目id
        String itemId = req.getItemId();
        TrackingProcessItem trackingProcessItemOld = trackingProcessItemMapper.selectByPrimaryKey(itemId);
        if (trackingProcessItemOld==null){
            return ServiceResult.fail(ErrorCodes.PARAM_ERROR);
        }
        //流程项目删除
        trackingProcessItemMapper.deleteByPrimaryKey(itemId);
        return ServiceResult.ok(itemId);
    }


    /**
     * 【私有方法，辅助其他接口方法使用】 检查流程类别分类是否存在
     */
    private void checkTrackingCategoryId(String categoryId,String tenantId) {
        if (StringUtils.isBlank(categoryId)||StringUtils.isBlank(tenantId)){
            throw new DuoJuHeException(ErrorCodes.TRACKING_CATEGORY_NOT_EXIST);
        }
        TrackingCategory trackingCategory = trackingCategoryMapper.selectByPrimaryKey(categoryId);
        if(trackingCategory==null || !SystemEnum.STATUS.NORMAL.getKey().equals(trackingCategory.getStatusCode())){
            throw new DuoJuHeException(ErrorCodes.TRACKING_CATEGORY_NOT_EXIST);
        }
        if (!tenantId.equals(trackingCategory.getTenantId())){
            throw new DuoJuHeException(ErrorCodes.TRACKING_CATEGORY_NOT_EXIST);
        }
    }
}
